fix(agents): normalize Command-wrapped tool results - #4977
fix(agents): normalize Command-wrapped tool results#4977BetterAndBetterII wants to merge 4 commits into
Conversation
Command-wrapped ToolMessages skipped result metadata and progress tracking, so error receipts could be recorded as success.
| continue | ||
| if tool_call_id and str(message.tool_call_id) != tool_call_id: | ||
| continue | ||
| normalize_tool_message(message) |
There was a problem hiding this comment.
[P1] Delegated task failures still get a success receipt through this path. _task_result_command carries the authoritative subagent_status (failed, cancelled, timed_out, or polling_timed_out) but leaves ToolMessage.status at LangChain's default success; its text starts with Task failed... / Task cancelled..., not the Error: prefix that normalize_tool_message recognizes. As a result this call stamps deerflow_tool_meta.status="success", and the outer receipt layer records success as well. I reproduced all four non-completed statuses with the production error-handling + receipt chain. Please derive task metadata from the structured subagent_status (or stamp it in _task_result_command) and add regression cases for these statuses, otherwise one of the principal Command producers named in #4976 remains unfixed.
willem-bd
left a comment
There was a problem hiding this comment.
The Command handling is correct for the newly covered setup_agent/view_image cases, but delegated task failures remain misclassified: failed, cancelled, timed-out, and polling-timeout task results all receive deerflow_tool_meta.status=success and therefore a success receipt. I reproduced this against the current head using the production error-handling and receipt chain. Please use the structured subagent_status when normalizing task results and add coverage for the non-completed statuses. Details are in the inline comment.
Delegated task Commands leave ToolMessage.status at success and do not use an Error: content prefix, so normalize_tool_message was labeling failed/cancelled/timed_out results as success. Honor structured subagent_status before content heuristics and cover the four statuses.
|
Addressed the delegated-task case: |
|
@BetterAndBetterII, please fix the lint error by running 'make format ' in the backend directory. |
willem-bd
left a comment
There was a problem hiding this comment.
The previously reported delegated-task status issue is fixed at this head, and the PR-specific regression tests pass. One CI blocker remains: the newly edited result-meta test file is not Ruff-formatted. Details are in the inline comment.
| assert m["error_type"] == expected_error_type, f"{content!r} → expected {expected_error_type!r}, got {m['error_type']!r}" | ||
|
|
||
| # --------------------------------------------------------------------------- | ||
| # Structured subagent_status failures (delegated task Command results) |
There was a problem hiding this comment.
[P1] Format this block so backend lint can pass
The required lint-backend check currently fails because uv run ruff format --check . reports that this file would be reformatted. Ruff only requires an additional blank line before this section header, but the formatting diff needs to be committed before the PR can pass CI.
Closes #4976
Why
ToolMessages returned insideCommand(update={"messages": [...]})skip result normalization and progress tracking. Error payloads then get a defaultsuccessreceipt even though the content isError: ....What changed
normalize_tool_resultnow stamps matchingToolMessages inside aCommand(same metadata contract as a bare result; producer-supplied meta is left alone).ToolErrorHandlingMiddlewarepasses the currenttool_call_idinto that normalization.ToolProgressMiddlewareassesses the matching Command message instead of ignoring everyCommand.Receipts already match Command messages by
tool_call_id; they now see the normalized status.Surface area
langgraph.json, or prompt changeBug fix verification
backend/tests/test_command_tool_result_semantics.pymain, green on this branch: yessetup_agent/view_imagethrough the production middleware chain.Validation
20 new tests passed. Related suites passed except one pre-existing
test_build_subagent_runtime_middlewares_threads_app_config_to_llm_middlewareordering failure onmain.AI assistance
Tool(s) used: none
How you used it: n/a